

#ifndef SCENE_H
#define SCENE_H

#include <gfx/enum.h>
#include <scene/entitynode.h>
#include <scene/geometry.h>
#include <scene/groupnode.h>
#include <scene/lodnode.h>
#include <scene/scene.h>
#include <scene/sector.h>
#include <materialmanager.h>
#include <btBulletCollisionCommon.h>

class ManualLevelOfDetailSolver : public iLevelOfDetailSolver
{
  CE_OBJECT
private:
  unsigned _num;
  unsigned _entry;

public:
  ManualLevelOfDetailSolver ();

  void SetNum (unsigned num);
  unsigned GetNum () const;
  void SetEntry (unsigned entry);
  unsigned GetEntry () const;

  unsigned Solve(unsigned numStages, float distance) const;
};

class Geometry : public ceGeometry
{
  CE_OBJECT
private:
  QString     _meshFilename;
  ceMeshType  _meshType;
  Material*   _material;

  btTriangleMeshShape*  _triMeshShape;

public:
  Geometry(iMesh* mesh = 0, Material* material= 0);
  virtual ~Geometry();

  void SetMetaMesh (ceMeshType type, const QString& filename);
  void SetMetaMaterial(Material* material);

  const QString& GetMetaMeshFilename () const;
  ceMeshType GetMetaMeshType () const;

  QString GetMetaMaterialName () const;

  btTriangleMeshShape* GetTriangleMeshCollisionShape ();
  void ReleaseTriangleMeshCollisionShape ();

};

class Scene;
class Sector;
class EntityNode;
class GroupNode;
class LODNode;
class EditorSceneNode : public QObject
{
  Q_OBJECT
public:
  enum NodeType
  {
    NodeType_Scene,
    NodeType_Sector,
    NodeType_EntityNode,
    NodeType_GroupNode,
    NodeType_LODNode
  };

private:
  bool    _selectable;

  bool    _selected;

  bool    _composition;

  NodeType  _nodeType;

protected:
  EditorSceneNode (NodeType type);

public:

  static EditorSceneNode* FromNode (ceNode* node);

  virtual Scene* ToScene () { return 0; }
  virtual Sector* ToSector () { return 0; }
  virtual EntityNode* ToEntityNode () { return 0; }
  virtual GroupNode* ToGroupNode () { return 0; }
  virtual LODNode* ToLODNode () { return 0; }

  bool IsSelectable () const;
  void SetSelectable (bool selectable);

  bool IsSelected () const;
  void SetSelected (bool selected);

  bool IsComposition () const;
  void SetComposition (bool composition);

  NodeType GetNodeType () { return _nodeType; }

  void Change ();
signals:

  void Changed (EditorSceneNode* node);

};

class Scene : public ceScene,
              public EditorSceneNode
{
public:
  Scene () : ceScene (), EditorSceneNode(NodeType_Scene) { }

  Scene* ToScene () { return this; }
};


class Sector : public ceSector,
               public EditorSceneNode
{
public:
  Sector () : ceSector (), EditorSceneNode (NodeType_Sector) { }

  Sector* ToSector () { return this; }
};





class EntityNode : public ceEntityNode,
                   public EditorSceneNode
{
public:
  EntityNode () : ceEntityNode (), EditorSceneNode (NodeType_EntityNode) { }

  EntityNode* ToEntityNode () { return this; }
};





class GroupNode : public ceGroupNode,
                  public EditorSceneNode
{
public:
  GroupNode () : ceGroupNode(), EditorSceneNode (NodeType_GroupNode) { }

  GroupNode* ToGroupNode () { return this; }
};




class LODNode : public ceLODNode,
                public EditorSceneNode
{
private:
  ManualLevelOfDetailSolver *_solver;


public:
  LODNode ();
	virtual ~LODNode ();

  LODNode* ToLODNode() { return this; }


  ManualLevelOfDetailSolver* GetSolver ();

};



#endif // SCENE_H
